import { app, shell, BrowserWindow, ipcMain, session, WebContentsView } from 'electron'
import log from 'electron-log'
import path from 'path'
import fs from 'fs'
import { electronApp, optimizer, is } from '@electron-toolkit/utils'
import icon from '../../resources/icon.png?asset'
//import { SerialPort } from 'serialport'
import { autoUpdater } from 'electron-updater'
import userConfig from './config'

log.transports.file.level = 'info'

// 设置自动更新
autoUpdater.autoDownload = false // 不自动下载，让用户选择
autoUpdater.autoInstallOnAppQuit = false // 退出时自动安装
autoUpdater.logger = log

let mainWindow

// 确保应用是单实例的
const gotTheLock = app.requestSingleInstanceLock()

if (!gotTheLock) {
  // 如果已经有一个实例在运行，就退出当前实例
  app.quit()
} else {
  app.on('second-instance', () => {
    // 当运行第二个实例时，将会聚焦到 mainWindow 窗口
    if (mainWindow) {
      if (mainWindow.isMinimized()) mainWindow.restore()
      mainWindow.focus()
    }
  })
}

function createWindow(): void {
  // Create the browser window.
  mainWindow = new BrowserWindow({
    width: 1200,
    height: 800,
    show: false,
	  frame: true,
    minWidth: 1024,
    minHeight: 800,
    autoHideMenuBar: true,
    icon,
    ...(process.platform === 'linux' ? { icon } : {}),
    webPreferences: {
      webSecurity: false, // 禁用同源策略
      preload: path.join(__dirname, '../preload/index.js'),
      sandbox: false,
      contextIsolation: false, // 禁用上下文隔离
      nodeIntegration: true,   // 启用 Node.js 集成
    }
  })

  mainWindow.maximize()


  // 处理窗口操作
  ipcMain.handle('window-minimize', () => {
    mainWindow.minimize();
  })

  ipcMain.handle('window-maximize', () => {
    if (mainWindow.isMaximized()) {
      mainWindow.unmaximize();
    } else {
      mainWindow.maximize();
    }
  });

  ipcMain.handle('window-close', () => {
    mainWindow.close();
  });

  ipcMain.handle('check-for-updates', async () => {
    return await autoUpdater.checkForUpdates()
  });

  ipcMain.handle('download-update', async () => {

    return await autoUpdater.downloadUpdate()
  })

  ipcMain.handle('quit-and-install', () => {
    autoUpdater.quitAndInstall()
  })

  /**
   * 获取本地配置文件
   */
  ipcMain.handle('get-config', () => {
    if(!app.isPackaged){
      return userConfig
    }
    else{
      const configPath = path.join(path.dirname(app.getPath('exe')), 'user.config')
      try {
        if(!fs.existsSync(configPath)){
          fs.writeFileSync(configPath, JSON.stringify(userConfig))
        }
        const data = fs.readFileSync(configPath, 'utf8')
        return JSON.parse(data)
      } catch (err) {
        console.error('Error reading config file:', err)
        return userConfig
      }
    }
  })

  /**
   * 设置cookie
   */
  ipcMain.handle('set-cookie', async (_event, cookieDetails) => {
    const defaultSession = session.defaultSession
    try {
      await defaultSession.cookies.set(cookieDetails)
      return { success: true }
    } catch (error) {
      return { success: false, error: (error as any).message }
    }
  })

  // 获取cookie
  ipcMain.handle('get-cookies', async (_event, url) => {
    const defaultSession = session.defaultSession
    try {
      const cookies = await defaultSession.cookies.get({ url })
      return { success: true, cookies }
    } catch (error) {
      return { success: false, error: (error as any).message }
    }
  })

  // 删除cookie
  ipcMain.handle('delete-cookie', async (_event, url, name) => {
    const defaultSession = session.defaultSession
    try {
      await defaultSession.cookies.remove(url, name)
      return { success: true }
    } catch (error) {
      return { success: false, error: (error as any).message }
    }
  })


  // 存储所有窗口的引用
  const newWindows:Set<BrowserWindow> = new Set()

  /**
   * 打开新窗口
   */
  ipcMain.handle('open-new-window', async (_event, url, options, inject) => {
    const widnowOptions = {
      width: 400,
      height: 300,
      parent: mainWindow, // 设置为父窗口，这样新窗口会显示在主窗口之上
      autoHideMenuBar: true,
      show: false, // 待页面加载后显示
      modal: true, // 设置为模态窗口，如果需要
      icon,
      ...options
    }

    const newWindow = new BrowserWindow(widnowOptions);

    if(inject){
      newWindow.webContents.on('did-finish-load', () => {
        if(inject.script){
          newWindow.webContents.executeJavaScript(inject.script)
        }
      });
    }

    newWindow.once('ready-to-show', () => {
      setTimeout(() => {
        newWindow.show()
        newWindow.focus()
      }, options.timeout|| 1);

    })





    newWindow.loadURL(url); // 加载新窗口的HTML文件



    // 创建一个 BrowserView
    // const view = new BrowserView({
    //   webPreferences: {
    //     nodeIntegration: false
    //   }
    // })
    // newWindow.setBrowserView(view)
    // view.setBounds({ x: 0, y: 0, width: 500, height: 300 }) // 设置视图的位置和大小
    // view.webContents.loadURL('https://baidu.com') // 加载你要显示的页面


    newWindow.on('closed', () => {
      newWindows.delete(newWindow)
    })

    newWindows.add(newWindow)

    return { success: true, id : newWindow.id }


  })


  // 监听关闭窗口的消息
  ipcMain.handle('close-new-window', (_event, windowId) => {
    let windowToClose:BrowserWindow|null = null
    for (const win of newWindows) {
      if (win.id === windowId) {
        windowToClose = win
        break
      }
    }
    if (windowToClose) {
      windowToClose.close()
      return { success: true }

    }
    return { success: false, error: 'Window not found' }
  })


  // 查询窗口
  ipcMain.handle('find-new-window', (_event, windowId) => {
    let window:BrowserWindow|null = null
    for (const win of newWindows) {
      if (win.id === windowId) {
        window = win
        break
      }
    }
    if(window){
        return { success: true, window : window }
    }
    else{
      return { success: false, error: 'Window not found' }
    }

  })


  const activeWebViews = new Map<string, WebContentsView>()
  const boundsMap = new Map<string, any>()

  mainWindow.on('resize', () => {
    const winBounds = mainWindow.getBounds()
    activeWebViews.forEach((webview: WebContentsView, id: string) => {
      const viewBounds = boundsMap.get(id)
      if (viewBounds) {
        const x = viewBounds.x || viewBounds.left || 0
        const y = viewBounds.y || viewBounds.top || 0
        const width =
          viewBounds.width !== undefined
            ? viewBounds.width
            : winBounds.width - x - viewBounds.right || 0
        const height =
          viewBounds.height !== undefined
            ? viewBounds.height
            : winBounds.height - y - viewBounds.bottom || 0
        const bounds = {
          x: x,
          y: y,
          width: width,
          height: height
        }
        webview.setBounds(bounds) // 设置视图的位置和大小
      }
    })
  })

  /**
   * 打开新窗口
   */
  ipcMain.handle('open-web-view', async (_event, url, options, inject) => {
    let webview: WebContentsView | undefined = undefined
    const webviewId = options.id || 'common'
    if (activeWebViews.has(webviewId)) {
      webview = activeWebViews.get(webviewId)
      console.log('已存在webview ID :' + webviewId)
    }

    if (!webview) {
      // 创建一个 BrowserView
      webview = new WebContentsView({
        webPreferences: {
          preload: path.join(__dirname, '../preload/index.js'),
          nodeIntegration: true
        },
        ...options
      })
      if (is.dev){
         webview.webContents.openDevTools()
      }

      mainWindow.contentView.addChildView(webview)
    }

    if (options.bounds) {
      const winBounds = mainWindow.getBounds()
      const viewBounds = options.bounds
      const x = viewBounds.x || viewBounds.left || 0
      const y = viewBounds.y || viewBounds.top || 0
      const width =
        viewBounds.width !== undefined
          ? viewBounds.width
          : winBounds.width - x - viewBounds.right || 0
      const height =
        viewBounds.height !== undefined
          ? viewBounds.height
          : winBounds.height - y - viewBounds.bottom || 0


      const bounds = {
        x: x,
        y: y,
        width: width,
        height: height
      }
      console.log(bounds)
      webview.setBounds(bounds) // 设置视图的位置和大小
      boundsMap.set(webviewId, options.bounds)
    }

    webview.webContents.loadURL(url) // 加载你要显示的页面



    webview.webContents.on('did-finish-load', () => {
      const listenLinks = inject.links
      const script = (listenLinks && listenLinks.length > 0) ? `
        if(globalThis.electron){
          // 保存原始方法
          const originalFetch = globalThis.fetch;


          // 重写 fetch
          globalThis.fetch = function (...args) {
            return originalFetch.apply(this, args).then((response) => {
              const url = args[0];
              const baseUrl = url.split('?')[0]
              console.log(baseUrl);
              if(${JSON.stringify(listenLinks)}.includes(baseUrl)){
                const clonedResponse = response.clone()
                clonedResponse.text().then((responseText) => {
                  // 发送响应内容到主进程
                  electron.ipcRenderer.send('http-response', {
                    url: args[0],
                    method: args[1],
                    status: response.status,
                    response: responseText
                  })
                })
              }
              return response
            })
          }

          if (globalThis.XMLHttpRequest) {
            // 拦截 XMLHttpRequest
            const originalOpen = globalThis.XMLHttpRequest.prototype.open
            const originalSend = globalThis.XMLHttpRequest.prototype.send

            globalThis.XMLHttpRequest.prototype.open = function (...args) { // (method, url)
              this._method = args[0]
              this._url = args[1]
              return originalOpen.apply(this, args)
            }

            globalThis.XMLHttpRequest.prototype.send = function (...args) {
              const url = this._url;
              const baseUrl = url.split('?')[0]
              console.log(baseUrl);
              if(${JSON.stringify(listenLinks)}.includes(baseUrl)){
                this.addEventListener('readystatechange', () => {
                  if (this.readyState === 4) {
                    electron.ipcRenderer.send('http-response', {
                      url: url,
                      method: this._method,
                      response: this.responseText
                    })
                  }
                })
              }
              return originalSend.apply(this, args)
            }
          }
        }

        ${inject.script || ''} ` : inject.script

      //script = inject.script
      if (script) {
        webview.webContents.executeJavaScript(script)
      }
    })

    // 监听 webContents 的 'destroyed' 事件
    webview.webContents.on('destroyed', () => {
      console.log(`WebContentsView ID: ${webviewId} 的 webContents 已被销毁`)
    })

    activeWebViews.set(webviewId, webview)
    return { success: true, id: webviewId }
  })

  ipcMain.handle('close-web-view', (_event, webviewId) => {
    const webView: WebContentsView|undefined = activeWebViews.get(webviewId)
    if (webView) {
      mainWindow.contentView.removeChildView(webView)
      activeWebViews.delete(webviewId)
      boundsMap.has(webviewId) && boundsMap.delete(webviewId)
      return { success: true }
    }
    return { success: false, error: 'WebView not found' }
  })

  /**
   * http响应监听
   */
  ipcMain.on('http-response', (_event, data) => {
    console.log(data);
    const dataPath = path.join(path.dirname(app.getPath('exe')), 'data.json')
    console.log(dataPath)
    fs.writeFileSync(dataPath, JSON.stringify(data))

  })

  /**
   * 执行脚本
   */
  ipcMain.handle('execute-javascrpt', (_event, webviewId, script) => {
    const webview: WebContentsView|undefined = activeWebViews.get(webviewId)
    if (webview) {
      webview.webContents.executeJavaScript(script).then(resp => {
        console.log(resp)
      })
    }
    return { success: true, id: webviewId }
  })

  mainWindow.on('ready-to-show', () => {
    mainWindow.show()
  })

  mainWindow.webContents.setWindowOpenHandler((details) => {
    shell.openExternal(details.url)
    return { action: 'deny' }
  })

  const defaultSession = session.defaultSession
  // 监听cookie的变化
  defaultSession.cookies.on('changed', (_event, cookie) => {
    mainWindow.webContents.send('cookie-changed', cookie);
  })

  defaultSession.webRequest.onCompleted( (details: Electron.OnCompletedListenerDetails) => {
    const uploadData = (details as any).uploadData
    if (uploadData && uploadData.length > 0) {
      const response = {
        url: details.url,
        method: details.method,
        headers: details.responseHeaders,
        statusCode: details.statusCode
      }
      const data = uploadData[0];
      //console.log("数据类型：" + data.type);
      if (data.type === 'rawData') {
        response['body'] = data.bytes.toString()
      }
      // console.log(response);
    }
  })

  // HMR for renderer base on electron-vite cli.
  // Load the remote URL for development or the local html file for production.
  if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
    mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL'])
    mainWindow.webContents.openDevTools()
  } else {
    mainWindow.loadFile(path.join(__dirname, '../renderer/index.html'))
    //mainWindow.webContents.openDevTools()
  }
}

// 更新事件处理
autoUpdater.on('checking-for-update', () => {
  console.log('检查更新中...')
  mainWindow.webContents.send('update-status', '检查更新中...')
})

autoUpdater.on('update-available', (info) => {
  console.log('发现新版本:', info);
  mainWindow.webContents.send('update-available', info);
})

autoUpdater.on('update-not-available', () => {
  mainWindow.webContents.send('update-status', '已是最新版本')
})

autoUpdater.on('download-progress', (progressObj) => {
  console.log('下载进度:', progressObj)
  mainWindow.webContents.send('download-progress', progressObj)
})

autoUpdater.on('update-downloaded', (info) => {
  mainWindow.webContents.send('update-downloaded', info)
})

autoUpdater.on('error', (err) => {
  mainWindow.webContents.send('update-error', err.message)
})

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(() => {

  app.userAgentFallback = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36'

  // Set app user model id for windows
  electronApp.setAppUserModelId('com.xmappservice.crawler')

  // Default open or close DevTools by F12 in development
  // and ignore CommandOrControl + R in production.
  // see https://github.com/alex8088/electron-toolkit/tree/master/packages/utils
  app.on('browser-window-created', (_, window) => {
    optimizer.watchWindowShortcuts(window)
  })

  // IPC test
  ipcMain.on('ping', () => console.log('pong'))

  createWindow()

  app.on('activate', function () {
    // On macOS it's common to re-create a window in the app when the
    // dock icon is clicked and there are no other windows open.
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })

  setTimeout(() => {
    autoUpdater.checkForUpdates()
  }, 5000)
})

// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit()
  }
})
